package me.zxc.crawler.model;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import me.zxc.domain.ModelNode;
import me.zxc.utils.ExportUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 模型平台爬虫（拼接好的模型路径）
 *
 * @author zhangxucheng
 * @version 1.0
 * @since 2022/8/25
 */
@Slf4j
public class ModelParser2 {

    /**
     * 中文CH 英文EN
     */
    public static final String MODULE_TYPE = "EN";
    /**
     * 根据观察，init接口的type参数总计就只有三种类型
     * 检索模型-case、抽取模型-extract、知识库模型-repository
     */
    public static final String TYPE = "case";
    /**
     * 模型平台权限认证用的是cookie，不加请求头会无法访问
     */
    public static final String COOKIE = "JSESSIONID=A65770009544C0C2570D4A92DB2CA2AE";
    /**
     * init 接口地址
     */
    public static final String INIT_URL = "http://192.168.8.20:8880/case/common/init";
    /**
     * son 接口地址
     */
    public static final String SON_URL = "http://192.168.8.20:8880/case/common/search/son";

    private static final Map<String, String> headerMap;

    static {
        headerMap = new HashMap<>();
        headerMap.put("Cookie", COOKIE);
    }

    public static void main(String[] args) {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("type", TYPE);
        Document document = null;
        try {
            document = Jsoup.connect(INIT_URL).data(paramMap).headers(headerMap)
                    .ignoreContentType(true)
                    .post();
        } catch (IOException e) {
            log.error("init接口 连接异常，请重试！", e);
        }
        if (document == null) {
            log.warn("init接口 未获取到数据，请更新cookie后重试！");
            return;
        }
        JSONObject initRoot = JSON.parseObject(document.body().html());
        // 这个就是son接口需要的参数里面的version
        String version = initRoot.getString("version");
        JSONArray rootList = initRoot.getJSONArray("list");
        if (CollUtil.isEmpty(rootList)) {
            log.warn("父级模型路径为空或未获取到！");
        }
        int totalParentNum = rootList.size();
        // 根路径层级
        ArrayList<String> dataList = new ArrayList<>();
        for (int i = 0; i < totalParentNum; i++) {
            JSONObject rootObj = rootList.getJSONObject(i);
            Boolean hasChild = rootObj.getBoolean("isHaveSon");
            String parentEntryName = rootObj.getString("entryName");
            String enName = rootObj.getString("fieldName");
            log.info("##数据绝赞获取中 -> 当前处理进度({}/{})：{}", i + 1, totalParentNum, parentEntryName);
            if (hasChild) {
                // 有孩子结点 取孩子结点的dataType 开始递归
                String dataType = rootObj.getString("dataType");
                if ("CH".equalsIgnoreCase(MODULE_TYPE)) {
                    traverseChildNode(version, dataType, parentEntryName, dataList);
                } else {
                    traverseChildNode(version, dataType, enName, dataList);
                }
            }
            // 防止把模型平台跑崩
            try {
                TimeUnit.MILLISECONDS.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        String outputStr = String.join("\n", dataList);
        ExportUtil.createPlaintext(outputStr, "d:\\","en-modules");
    }

    /**
     * son接口解析，递归获取孩子结点数据
     *
     * @param version         son接口参数
     * @param dataType        son接口参数（类似id之类的东西）
     * @param parentEntryName 父级模型名
     * @param dataList        存储路径结果集
     * @return 全部孩子结点
     */
    private static void traverseChildNode(String version, String dataType, String parentEntryName, List<String> dataList) {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("version", version);
        paramMap.put("dataType", dataType);
        paramMap.put("jsonObj", "{}");
        paramMap.put("vague", "");
        paramMap.put("type", TYPE);
        Document document = null;
        try {
            document = Jsoup.connect(SON_URL).data(paramMap).headers(headerMap)
                    .ignoreContentType(true)
                    .post();
        } catch (IOException e) {
            log.error("son接口 连接异常，请重试！", e);
        }
        if (document == null) {
            log.warn("son接口 未获取到数据，请更新cookie后重试！");
            return;
        }
        JSONArray sonArr = JSON.parseArray(document.body().html());

        for (int i = 0; i < sonArr.size(); i++) {
            JSONObject oneSon = sonArr.getJSONObject(i);
            Boolean hasChild = oneSon.getBoolean("isHaveSon");
            String chName = oneSon.getString("entryName");
            String enName = oneSon.getString("fieldName");
            String sonDataType = oneSon.getString("dataType");
            String separator, name;
            if ("CH".equalsIgnoreCase(MODULE_TYPE)) {
                separator = "_";
                name = chName;
            } else {
                separator = ".";
                name = enName;
            }
            String levelName = parentEntryName + separator + name;
            if (hasChild) {
                traverseChildNode(version, sonDataType, levelName, dataList);
            }
            dataList.add(levelName);
        }
    }
}
